CODv2 3.12 実例:Intel 80x86 の命令
CODv2 3.12 実例:Intel 80x86 の命令
( CODv3 (第3版)では呼称が IA-32 になっている)
( CODv4 (第4版)以降では呼称が x86 になっている
Intel 80x86 ( IA-32 )
x86(エックスはちろく)は、Intel 8086で16ビット用、i386で32ビット用の仕様が初めて誕生した後に引き続き後継チップが開発され、その命令セットアーキテクチャ、およびそれと互換性を備えた命令セットを持つマイクロプロセッサ群の総称である。
この命令セットアーキテクチャをもつプロセッサの型番が、最初の段階で「8086」、「80186」、「80286」、「80386」、「80486」と続いたため、総称して「80x86」、
更に型番の下2桁が共通するところから「x86」(エックスはちろく、ペケはちろく)や「86系」などと呼ぶようになった。
これらは初期の8086から80286までの16ビットのプロセッサの通称として始まり、主にユーザーや互換チップメーカーが用いた。同時期のモトローラのライバル的MPU「MC68000」と、そのファミリーがやはり型番から「68系」と呼ばれたので、それと対比するためにも用いるようになった。
IA-32(アイエー32、Intel Architecture 32)は80386の開発の際に定義された、16ビットx86を32ビットに拡張した命令セットアーキテクチャである。
IA-32という呼称自体は、インテルが新しい64ビットアーキテクチャであるIA-64を発表した際に、それと対比して従来の32ビットアーキテクチャ(すなわち、386以降その時までのx86、及びその時点から未来の同一ISAプロセッサ)を指すものとして作られた一種のレトロニムである。
レトロニム(英語: retronym)とは、ある語の意味が時代とともに拡張された、あるいは変化した場合に、古い意味の範囲を特定的に表すために後から考案された語のことを指す。
「レトロニム」という単語は、「過去」を意味する「レトロ(retro)」と「語」を意味する接尾辞(-onym)の合成語である。
つまり、時代の変化により新しい事物が生まれたことから、既存の事物を新しいものと区別するため「後から」つくられた言葉を「レトロニム」と呼ぶ。
一例を挙げれば、カメラにおいてデジタルカメラが出現したために「フィルムカメラ」の語が生まれ、またオンラインショップの普及により「実店舗」の語が生まれた。
概要
( CODv3 を参照する)
1985年当時、 MIPS は小さなグループのビジョンであった。このアーキテクチャの個々の部分は相互によく適合しあい、アーキテクチャ全体を簡潔に記述できた。
IA-32 は、そうではない。
IA-32 は20年以上にわたってアーキテクチャを発展させてきた、いくつかの独立したグループによる共同の産物である
その過程で元々の命令セットに新しい機能が盛り込まれてきた
例えて言えば、荷物を一度詰めたバッグにさらに追加の衣類を押し込むようなものである
歴史
1978
Intel 8086
8ビット・マイクロプロセッサ Intel 8080 のアセンブリ言語と互換性のある機能拡張と位置づけ
16ビット・アーキテクチャ
内部レジスタ長は 16 ビット
レジスタは専用化されていた。8086 は汎用レジスタ・アーキテクチャとはみなされない
汎用レジスタ
General-purpose register ( GPR )
任意の命令でアドレス用にもデータ用にも使用できるレジスタ
1980
intel 8087 浮動小数点コプロセッサ
8006 を拡張
約60の浮動小数点命令を追加
レジスタを使用する代わりにスタックに依存
1982
intel 80286
8086 アーキテクチャを拡張
アドレス空間を24ビットに拡張
手の込んだメモリ・マッピングと記憶保護モデル(第7章)
8086 のプログラムを修正せずに実行可能
1985
Intel 80386
80286 アーキテクチャを32ビットに拡張
32ビット・レジスタ、および、32ビット・アドレス空間をそなえた32ビット・アーキテクチャに
新しいアドレシング・モードと命令操作が追加され、汎用レジスタ・マシンに近くなった
セグメント方式のアドレシング(第7章)に加えてページ方式がサポート
8086 のプログラムを修正せずに実行可能
1989
i486
1992
Pentium
いずれも性能向上を目的とする
命令セット上、ユーザーに見えるものは4つしか追加されていない
そのうち3つは、マルチプロセッシングをサポートするもの(第9章)
残りの1つは、条件付き移送命令( move )
1997
MMX
Pentium および Pentium Pro が出荷されたあとこの2つを MMX で拡張することを発表
MMXは、インテルが同社のPentiumプロセッサ向けに開発した SIMD 型拡張命令セットである。56個の命令を含む。MMXは、MultiMedia eXtensionsの略であるとの説があったが、インテルは、略語ではない一つの語であるとしている。
単一命令・複数データ(英: single instruction, multiple data、SIMD)とはコンピューターの演算処理に関するフリンの分類のひとつで、1つの命令を同時に複数のデータに適用する並列化の形態を指す。
この手法にもとづく演算をベクトル演算 (vector operation) と呼ぶこともある。
通例、SIMD命令により同時処理するのに適したデータ構造あるいはデータ型を利用するため、命令実行の前に処理対象のデータ列はいったん結合(パック)され、処理完了後に分解(アンパック)される。結合されたデータはpacked data(パックデータ、パックトデータ)と呼ばれる。
新たに57の命令を追加
単一命令・複数データ( SIMD )アプリケーション(第9章)の伝統に従い、同時に複数の短いデータ要素を操作できる
1999
SSE
ストリーミングSIMD拡張命令(英: Streaming SIMD Extensions、略称:SSE)は、インテルが開発したCPUのSIMD拡張命令セット、およびその拡張版の総称である。
70の命令を追加
SSE レジスタを8本追加
この SSE レジスタのデータ幅を128ビットに
単精度浮動小数点データ型を追加
これらにより、32ビットの浮動小数点の演算操作を4つ並行して実行可能
メモリの性能を向上させるために、キャッシュ・プリフェッチ命令に加えて、
キャッシュ・プリフェッチは、中央処理装置(CPU)が、命令やデータを実際に必要になる前に、低速メモリ内の主記憶装置(メインストレージ)から高速なローカルメモリへフェッチすることで実行性能を向上させる技術である。
最近のCPUのほとんどは高速なローカルキャッシュメモリを備えており、プリフェッチされたデータは必要になるまでそこに保持される。
プリフェッチ操作のソースは通常、メインメモリである。
その設計上、キャッシュメモリへのアクセスは通常、メインメモリへのアクセスよりもはるかに高速である。
プリフェッチは、非ブロッキング・キャッシュ制御命令を用いて行うことができる。
メモリに直接書き込むストリーミング・ストア命令も追加
2001
SSE2
SSE2は従来のSSEに144個の新たな命令が加えられた。具体的には64ビットの倍精度浮動小数点演算のサポートおよびMMXを128ビット幅に拡張する整数演算命令の追加、キャッシュの制御機能の強化がなされた。
SSE2はPentium 4で初めて実装された。
追加されたデータ型は倍精度の算術演算。これにより64ビットの浮動小数点演算を2つ並行して実行可能
144の命令を追加
これらの命令の大部分は64ビットのデータを並列に処理できるように MMX および SSE の命令を改訂したもの
コンパイラから見ると、従来の独特のスタック・アーキテクチャ以外の浮動小数点処理の対象が生まれた
コンパイラは SSE レジスタを8本合わせて、浮動小数点レジスタとして使用することを選択可能
2003
AMD64
Intel 以外の会社が IA-32 アーキテクチャを拡張
アドレス空間を32ビットから64ビットへ
すべてのレジスタの幅を64ビット化し、レジスタ数を16に増加
128ビットの SSE レジスタを16に増加
ロング・モード
すべての IA-32 命令の実行を64ビットのアドレスとデータで再定義する「ロング・モード」と呼ばれる新しいモードを追加
増大したレジスタ数に対応するために命令に新しいプリフィックスを追加
(数え方によるが)新しい命令が4ないし10追加され、27の古い命令が削除された
PC 相対アドレシングを追加
それ以外の2つのモード
レガシー・モード
IA-32 と同じモード
互換モード
ユーザー・プログラムは IA-32 に限定するが、オペレーティング・システムでは AMD64 を使用するモード
2004
Intel64 ( IA-32e / EM64T )
SSE3
まとめ
以上の歴史は IA-32 が互換性に縛られていることを示している
大幅なアーキテクチャの変更があるたびに、既存の膨大かつ重要なソフトウェア資産の互換性を損なうことができなかった
留意するべき点
アーキテクチャの洗練度の観点からどのような不備があろうと、このアーキテクチャ・ファミリーは世界中で他のいかなるものよりもデスクトップ上に数多く存在する
しかしながら
パッチワークの歴史ともいえるこのアーキテクチャは説明するのが困難である
これ以降の心構え
IA-32 のプログラムを組むときに必要になるような注意を払わないこと
この節での意図は、この世界で最も普及しているアーキテクチャの強みと弱みを把握することにある
全体を示す代わりに、80386 プロセッサに端を発する32ビットの命令のサブセットを重点的に説明する
レジスタとアドレシング・モード
命令セットの発展経緯は 80386 のレジスタに見ることができる
8086 のレジスタ構成は?
https://gyazo.com/386ae2351206343ef04d15d31bd6911b
80386 ではセグメント・レジスタ以外のレジスタが 32 ビットに拡張された
拡張されたレジスタには 32 ビット・バージョンであることがわかるように頭に E という文字が付けられた
これらを総称して GPR ( general-purpose register 汎用レジスタ)と呼ぶ
80386 には GPR が8本しかない
MIPS の平均的なプログラムでは約4倍?のレジスタを使用することができる
( MIPS でも用途は規定されていて、特定用途以外のレジスタは 24 個(全32個中)のはず)
(「汎用レジスタ」というのはそういう意味ではないのだろう)
(そもそもレジスタの構造が違う?)
( → 8086 のレジスタ構成を知らないとわからないことのような気がする)
算術、論理、データ転送の命令は2つのオペランドを持つ
table:80386 operand list
* ソース/デスティネーション・オペランド 第2のソース・オペランド
レジスタ レジスタ
レジスタ 即値
レジスタ メモリ
メモリ レジスタ
メモリ 即値
MIPS との大きな違い
IA-32 の算術命令および論理命令では、
1. 1つのオペランドがソースとデスティネーションを兼用しなければならない
ソース・レジスタの1つは必ず変更されてしまう(上書きされてしまう)
2. オペランドの1つをメモリに割り付けることができる
任意の命令の、オペランドの一方がメモリ中にあってもよい
メモリをオペランドとした場合、任意のアドレシング・モードを使用できるが、アドレシング・モードごとに使用できるレジスタには、下記の通り制限がある
1. モード: レジスタ間接アドレシング・モード
摘要:
アドレスはレジスタ中にある
レジスタの制約:
ESP または EBP 不可
MIPS での対応例:
lw $s0, 0($s1)
2. モード:ディスプレースメントが 8 または 32 ビットのベース相対アドレシング・モード
摘要:
アドレスはベース・レジスタの内容にディスプレースメントを加算したもの
レジスタの制約:
ESP または EBP 不可
MIPS での対応例:
lw $s0, 100($s1) # 16 ビット以下のディスプレースメント
3. モード:ベース相対 + スケール付きインデックス修飾アドレシング・モード
摘要:
アドレスは下記の式で与えられる
ベース + ( 2^スケール * インデックス)
ただしスケールの値は 0, 1, 2, 3 のいずれか
レジスタの制約:
ベースには任意の GPR
インデックスには ESP 不可
MIPS での対応例:
仮想的な乗算命令 mul
mul $t0, $s1, 4
add $t0, $t0, $s1
lw $s0, 0($s0)
4. モード:ディスプレースメントが 8 または 32 ビットのベース相対 + スケール付きインデックス修飾アドレシング・モード
摘要:
アドレスは下記の式で与えられる
ベース + ( 2^スケール * インデックス) + ディスプレースメント
ただしスケールの値は 0, 1, 2, 3 のいずれか
レジスタの制約:
ベースには任意の GPR
インデックスには ESP 不可
MIPS での対応例:
仮想的な乗算命令 mul
mul $t0, $s1, 4
add $t0, $t0, $s1
lw $s0, 100($s0) # 16 ビット以下のディスプレースメント
「ベース相対 + スケール付きインデックス修飾アドレシング・モード」が組み込まれている理由
レジスタ中のインデックスをバイト・アドレスに変えるために4倍(スケール係数が 2 )する操作を避けるため
このアドレシング・モードは MIPS と PowerPC には存在しない
スケール係数とデータサイズの関係
スケール係数 0
スケールがつかない
8ビット・データ?
スケール係数 1
16ビット・データ
スケール係数 2
32ビット・データ
スケール係数 3
64ビット・データ
2番目と4番目のモードで、ディスプレースメントが 16 ビットよりも長い場合、相当する MIPS コードにはさらに2つの命令が必要になる
lui 命令でディスプレースメントの上位 16 ビットをロード
add 命令でこの上位のアドレスとベース・レジスタの $s1 の和を求める
Intel では「ベース相対アドレシング・モード」に「ベース相対」と「インデックス修飾」という2つの名前をつけている
これらはほとんど同じものなので、ここでは1つにまとめる
整数演算
8086 では8ビットと16ビットの両方のデータ・タイプを扱える
8ビット(バイト単位 1バイト)
16ビット(語単位 2バイト)
80386 では32ビット・アドレスと32ビット・データである double word (倍長語)が追加された
データ・タイプの区別はメモリ・アクセスおよびレジスタ操作の両方に適用される
ほとんどの命令操作は8ビット・データと、より長いデータ・サイズを1つ扱える
そのサイズはアドレシング・モードによって決まり 16 ビットまたは 32 ビットのどちらかとなる
80386 の設計者は3つのサイズのデータをすべて扱うために、コード・サイズをあまり大きくしなくても、どちらの長さのデータを使用するか指定できる方法を用意した
ある前提:ほとんどのプログラムでは16ビット、32ビットのどちらか一方が圧倒的に多く使用される(はず)
長いデータ・サイズとしてどちらを使うかをデフォルト値として扱う
デフォルト値をコード・セグメント・レジスタ中の1ビットによって設定する
コード・セグメント・レジスタ ? CS?
デフォルトでない方のデータ・サイズを使いたいときには命令に8ビットのプリフィックスを付加して、もう一方の長いデータ・サイズを使用するようにマシンに指示する
8ビットのプリフィックス ?
プリフィックスを使用する解決策は 8086 の手法
8086 ではプリフィックスを使用して命令の動作を修正している
もともと使用されていたプリフィックスは3つ
1. デフォルトのセグメント・レジスタを上書き変更するもの
DS, ES, CS, SS, (FS, GS)
2. セマフォをサポートするためにバスをロックするもの
セマフォ(英: semaphore)とは、計算機科学において、並行プログラミング環境での複数の実行単位(主にプロセス)が共有する資源にアクセスするのを制御する際の、単純だが便利な抽象化を提供する変数または抽象データ型である。
3. レジスタ ECX が繰り下げられて 0 に達するまで次の命令を繰り返すもの
ECX ? CX ? (カウンタ・レジスタ ? )
これはバイト移送命令と対で使用して、可変長のバイトを移送することを意図したもの
80386 ではデフォルトのアドレス・サイズを上書き変更するプリフィックスも追加された
整数の操作は下記の4種類